package com.platform.study.thread;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * 用实现Runnable接口方式实现线程:线程同步
 * 注：在运用两步标识的时候，尽量使用同步块（同步块尽量最小），而不要使用同步方法
 * 在相同的环境下同步块的工作效率要优于同步方法
 *
 * User: wangyanginfo
 * Date: 12-11-26
 * Time: 下午2:44
 */
public class RunnableSimple_9 implements Runnable {

    private AtomicInteger ticket = new AtomicInteger(10);

    public int getValue() {
        return ticket.get();//这是原子方法
    }


    public void evenIncrement() {
        ticket.addAndGet(-1);//这是原子方法
    }

    @Override
    public void run() {
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 60; i++) {
            correctMethod();
        }
        long endTime = System.currentTimeMillis();
        System.out.println(endTime - startTime);
    }

    /**
     * 下面的方法正确处理同步过程 synchronized块
     */
    private void correctMethod() {
        synchronized (this) {
            if (getValue() > 0) {
                evenIncrement();
                System.out.println(Thread.currentThread().getName() + " 1运行 _  " + getValue());
            }
        }
        if (getValue() > 0) {
            try {
                System.out.println(Thread.currentThread().getName() + " sleep 1000 ");
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        synchronized (this) {
            if (getValue() > 0) {
                evenIncrement();
                System.out.println(Thread.currentThread().getName() + " 2运行 _  " + getValue());
            }
        }
    }

    public static void main(String[] args) {

        RunnableSimple_9 simpleA = new RunnableSimple_9();
        Thread thread1 = new Thread(simpleA, "线程1");
        Thread thread2 = new Thread(simpleA, "线程2");
        Thread thread3 = new Thread(simpleA, "线程3");
        thread1.start();
        thread2.start();
        thread3.start();

    }
}
